#ifndef _HLFS_ADDRESS_H_
#define _HLFS_ADDRESS_H_

#include <time.h>
#include <stdint.h>
#include <glib.h>
//#include "hlfs.h"

extern uint64_t SEGMENT_SIZE_MASK;
extern uint64_t SEGMENT_SIZE_SHIFT;

static uint32_t get_segno(uint64_t address)
{
    //return uint32_t((uint64_t)address >> SEGMENT_SIZE_SHIFT);
    return (uint64_t)address >> SEGMENT_SIZE_SHIFT;
}
static uint32_t get_offset(uint64_t address)
{
    return address & SEGMENT_SIZE_MASK;
}

static void set_segno(uint64_t *address, uint32_t segment_no)
{
    int64_t tmp = segment_no;
    tmp <<= SEGMENT_SIZE_SHIFT;
    *address = (*address & SEGMENT_SIZE_MASK) | tmp;
}

static void set_offset(uint64_t *address, uint32_t offset)
{
    *address = (*address & ~SEGMENT_SIZE_MASK) | offset;
} 

static gboolean is_db_in_level1_index_range(uint32_t db_no){
        if(db_no<12 && db_no >=0)
            return TRUE;
        else
            return FALSE;
}

static gboolean is_db_in_level2_index_range(uint32_t db_no){
        if(db_no < (1024 + 12) && db_no >= 12)
            return TRUE;
        else
            return FALSE;
}

static gboolean is_db_in_level3_index_range(uint32_t db_no){
         if(db_no<(1024*1024 + 1024 + 12 ) && db_no >= (1024+12))
             return TRUE;
         else
             return FALSE;
}

static gboolean is_db_in_level4_index_range(uint32_t db_no){
         if(db_no < (1024*1024*1024 + 1024*1024 + 1024 + 12) && db_no >= ((1024*1024) + 1024 + 12))
                return TRUE;
         else
                return FALSE;
}
static uint32_t ib_amount(uint32_t db_start, uint32_t db_end)
{
        uint32_t ib1;
        uint32_t ib2;
        uint32_t idx;
        uint32_t idx1;
        uint32_t idx2;

        if (is_db_in_level1_index_range(db_end))
                ib1 = 0;
        else if (is_db_in_level2_index_range(db_end))
                ib1 = 1;
        else if (is_db_in_level3_index_range(db_end))
                ib1 = 1 + 1 + (db_end - 12 - 1024) / 1024 + 1;
        else if (is_db_in_level4_index_range(db_end)) {
                idx = (db_end - 12 - 1024 - 1024 * 1024) / (1024 * 1024);
                idx2 = (db_end - 12 - 1024 - 1024 * 1024) % 1024;
                idx1 = ((db_end - 12 - 1024 - 1024 * 1024) - idx2 - 1) / 1024 % 1024;
                ib1 = 1 + (1 + 1024) + 1 + (idx1 + 1) + (idx * 1024 + 1);
        }
        if (is_db_in_level1_index_range(db_start) ||
                        is_db_in_level2_index_range(db_start))
                ib2 = 0;
        else if (is_db_in_level3_index_range(db_start))
                ib2 = (db_start - 12 - 1024) / 1024;
        else if (is_db_in_level4_index_range(db_start)) {
                idx = (db_start - 12 - 1024 - 1024 * 1024) / (1024 * 1024);
                idx2 = (db_start - 12 - 1024 - 1024 * 1024) % 1024;
                idx1 = ((db_start - 12 - 1024 - 1024 * 1024) - idx2 - 1) / 1024 % 1024;
                ib2 = idx + idx * 1024 + idx2;
        }
        return ib1 - ib2;
}
#endif
